package com.pb.metadata.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.pb.infra.oth.util.Constant;
import com.pb.infra.oth.util.JwtTokenConfig;
import com.pb.metadata.mapper.MateCodeValueMapper;
import com.pb.infra.oth.entity.common.Page;
import com.pb.infra.oth.entity.common.Result;
import com.pb.infra.oth.util.ExcelUtil;
import com.pb.infra.oth.util.StringUtil;
import io.jsonwebtoken.Claims;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * 码值管理模块
 * @author liurongjun
 * @date 2021/02/22
 */
@Service
public class MateCodeValueService {

    /**
     * 码值表DAO映射
     */
    @Resource
    private MateCodeValueMapper mateCodeValueMapper;

    /**
     * jwttoken配置类
     */
    @Resource
    private JwtTokenConfig jwtTokenConfig;

    /**
     * 查询分页数据
     *
     * @param map 查询参数
     * @param page 页码
     * @return
     */
    public Result selectByPage(Map<String, Object> map, Page page, HttpServletRequest request){
        String token = request.getHeader(jwtTokenConfig.getHeader());
        Claims claims = jwtTokenConfig.getClaimByToken(token);
        String userId = (String)claims.get(jwtTokenConfig.getSub());
        map.put("userId", userId);
        List<Map<String, Object>> list = new ArrayList<>();
        map.put("businessCodeType", StringUtil.isEmpty(map.get("businessCodeType")) ? null : map.get("businessCodeType").toString().toUpperCase(Locale.ENGLISH));
        List<Map<String, Object>> corpList = mateCodeValueMapper.selCorpListByUserId(map);
        corpList.removeAll(Collections.singleton(null));
        if (corpList != null && corpList.size() > 0) {
            map.put("corpList", corpList);
        }
        if (!StringUtil.isEmpty(map.get("codeTypeName"))) {
            List<String> list1 = mateCodeValueMapper.queryCodeTab();
            if (list1 != null && list1.size() > 0) {
                map.put("tableList", list1);
            }
        }
        if (page != null && page.getPageIndex() != null && page.getPageSize() != null) {
            PageHelper.startPage(page.getPageIndex(), page.getPageSize());
        }
        if (!StringUtil.isEmpty(map.get("selFlag")) && "1".equals(map.get("selFlag").toString())) {
            if (!StringUtil.isEmpty(map.get("corpId"))) {
                list = mateCodeValueMapper.selectByPage(map);
            } else {
                list = mateCodeValueMapper.selectByCorpPage(map);
            }
        } else {
            list = mateCodeValueMapper.selectByPage(map);
        }
        return Result.ok(new PageInfo(list).getTotal(), list);
    }

    /**
     * 查询码值存放类型
     *
     * @return
     */
    public Result getCodeStoreList(){
        List<Map<String,Object>> mapList = mateCodeValueMapper.getCodeStoreList();
        return Result.ok(mapList);
    }

    /**
     * 查询数据存放类型
     *
     * @return
     */
    public Result getDataStoreList(){
        List<Map<String,Object>> mapList = mateCodeValueMapper.getDataStoreList();
        return Result.ok(mapList);
    }

    /**
     * 查询码表对象名
     *
     * @return
     */
    public Result getCodeTableList(){
        List<Map<String,Object>> mapList = mateCodeValueMapper.getCodeTableList();
        return Result.ok(mapList);
    }

    /**
     * 保存码值相关信息
     *
     * @param paramMap 保存数据
     * @return
     */
    @Transactional
    public Result insert(Map<String, Object> paramMap, HttpServletRequest request){
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        paramMap.put("createTime", format.format(new Date()));
        paramMap.put("businessCodeType", paramMap.get("businessCodeType").toString().toUpperCase(Locale.ENGLISH));
        paramMap.put("debugFlag","0");
        String token = request.getHeader(jwtTokenConfig.getHeader());
        Claims claims = jwtTokenConfig.getClaimByToken(token);
        String userId = (String)claims.get(jwtTokenConfig.getSub());
        paramMap.put("userId", userId);
        Map<String, Object> IdAndTableName = mateCodeValueMapper.selectConstraits(paramMap);
        if(!StringUtil.isEmpty(IdAndTableName)){
            paramMap.put("codeTypeId", IdAndTableName.get("codeTypeId"));
            paramMap.put("oldTableName", IdAndTableName.get("tableName"));
            paramMap.put("oldTableId", IdAndTableName.get("codeTableId"));
            this.update(paramMap, request);
            return Result.OK_EMPTY;
        }else{
            String seq = mateCodeValueMapper.maxCodeTypeId();
            paramMap.put("deleteFlag","0");
            paramMap.put("debugFlag","0");
            paramMap.put("recordSts","FREE");
            paramMap.put("seq",StringUtil.isEmpty(seq)? "1" : Integer.parseInt(seq)+1);
            mateCodeValueMapper.insert(paramMap);
            return Result.OK_EMPTY;
        }
    }

    /**修改码值相关信息
     *
     * @param paramMap 保存数据
     * @return
     */
    @Transactional
    public Result update(Map<String, Object> paramMap, HttpServletRequest request){
        String token = request.getHeader(jwtTokenConfig.getHeader());
        Claims claims = jwtTokenConfig.getClaimByToken(token);
        String userId = (String)claims.get(jwtTokenConfig.getSub());
        paramMap.put("userId", userId);
        //迁移码值
        if(!paramMap.get("oldTableId").equals(paramMap.get("codeTableId"))) {
            //旧码表
            String tableName = paramMap.get("oldTableName").toString();
            Map<String, Object> map = new HashMap<>();
            map.put("tableName", tableName);
            map.put("codeTypeId", paramMap.get("codeTypeId"));
            List<Map<String, Object>> insertMap = mateCodeValueMapper.getIterDataList(map);
            //移除迁移之前的数据
            mateCodeValueMapper.removeIterData(map);
            //迁移码表
            tableName = paramMap.get("tableName").toString();
            map.put("tableName", tableName);
            String seq = mateCodeValueMapper.selectMaxCodeId(map);
            seq = StringUtil.isEmpty(seq) ? "0" : seq;
            if (insertMap.size() > 0) {
                List<Map<String, Object>> dataList = new ArrayList<>();
                Map<String, Object> newMap;
                int aimValue;
                for (Map recomMap : insertMap) {
                    seq = String.valueOf(Integer.parseInt(seq) + 1);
                    recomMap.put("id", seq);
                    if (!StringUtil.isEmpty(paramMap.get("corpId"))) {
                        recomMap.put("corpId", paramMap.get("corpId").toString());
                    }
                    if (StringUtil.isEmpty(recomMap.get("parentId").toString().trim())) {
                        recomMap.put("parentId", "");
                        recomMap.put("path", seq);
                    } else {
                        aimValue = containsByKey(dataList, recomMap.get("upBusinessCode").toString(), "businessCode");
                        newMap = dataList.get(aimValue);
                        recomMap.put("parentId", newMap.get("id"));
                        recomMap.put("path", newMap.get("path") + "." + seq);
                    }
                    dataList.add(recomMap);
                }
                String corpFlag = "0";
                if (!StringUtil.isEmpty(paramMap.get("corpId"))) {
                    corpFlag = "1";
                }
                batchInsertOrUpdate(map, dataList, "insert", corpFlag);
            }
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        paramMap.put("updateTime", format.format(new Date()));
        paramMap.put("businessCodeType", paramMap.get("businessCodeType").toString().toUpperCase(Locale.ENGLISH));
        paramMap.put("deleteFlag","0");
        mateCodeValueMapper.update(paramMap);
        return Result.OK_EMPTY;
    }

    /**
     * 删除码值信息
     *
     * @param list 请求参数
     */
    @Transactional
    public void delete(List<Map<String, Object>> list) {
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                Map<String, Object> map = list.get(i);
                String tabName = list.get(i).get("DATABASEUSER").toString() + "." + list.get(i).get("TABLENAME").toString();
                map.put("tableName", tabName);
                map.put("codeTypeId", list.get(i).get("CODETYPEID").toString());
                mateCodeValueMapper.deleteCodeByType(map);
                mateCodeValueMapper.delete(map);
            }
        }
    }

    /**
     * 启用停用相应码值
     *
     * @param paramMap
     */
    @Transactional
    public void startOrStop(List<Map<String,Object>> paramMap){
        for(Map map:paramMap){
            map.put("activeFlag","1".equals( map.get("activeFlag").toString())?"0":"1");
            mateCodeValueMapper.startOrStop(map);
        }
    }

    /**
     * 锁定码值信息
     *
     * @param map 请求参数
     */
    @Transactional
    public void lockedDate(List<String> map) {
        mateCodeValueMapper.lockedDate(map);
    }

    /**
     * 提交码值信息
     *
     * @param map 请求参数
     */
    @Transactional
    public void freeDate(List<String> map) {
        mateCodeValueMapper.freeDate(map);
    }

    /**
     * 查询迭代码值信息
     *
     * @param map
     * @param page
     * @return
     */
    public Result getIterDataList(Map<String, Object> map ,Page page){
        String tableName = mateCodeValueMapper.getTableName(map);
        map.put("tableName",tableName);
        List<Map<String, Object>> listSearchAll;
        //根据条件查询业务结点
        if (page != null && page.getPageIndex() != null && page.getPageSize() != null) {
            PageHelper.startPage(page.getPageIndex(), page.getPageSize());
            listSearchAll = mateCodeValueMapper.getIterDataList(map);
            return Result.ok(new PageInfo(listSearchAll).getTotal(),listSearchAll);
        } else {
            listSearchAll = mateCodeValueMapper.getIterDataList(map);
            map.put("cnName",null);
            map.put("upperDesc",null);
            map.put("remarks",null);
            map.put("businessCode",null);
            //所有业务结点
            List<Map<String, Object>> AllList = mateCodeValueMapper.getIterDataList(map);
            List<Map<String, Object>> aimAllList = new ArrayList<>(); // 目标业务节点
            // 根据每个查询到的节点，到所有节点集合中查找该节点及所有目录节点，去重
            for (Map<String, Object> listSearch : listSearchAll) {
                this.getSearchAllCodes(AllList, listSearch.get("id").toString(), aimAllList);
            }
            return Result.ok(aimAllList);
        }
    }

    /**
     * 查询目标结点
     *
     * @param allCodeList
     * @param codeId
     * @param aimCodeList
     */
    private void getSearchAllCodes(List<Map<String, Object>> allCodeList,String codeId,List<Map<String, Object>> aimCodeList){
        for (Map<String, Object> list : allCodeList) {
            if (list.get("id").toString().equals(codeId)) {
                if(!ifCodeListExit(codeId,aimCodeList)) {
                    // 将某个节点添加到结果集
                    aimCodeList.add(list);
                    // 如果该节点不是顶层节点，将上属节点添加到结果集
                    if (!" ".equals(list.get("parentId").toString())) {
                        this.getSearchAllCodes(allCodeList, list.get("parentId").toString(), aimCodeList);
                    }
                    break;
                }
            }
        }
    }

    /**
     * 判断业务口径结果集中是否已存在某节点
     *
     * @param codeId
     * @param aimCodeList
     * @return
     */
    private boolean ifCodeListExit(String codeId, List<Map<String, Object>> aimCodeList) {
        boolean exist = false;
        for (Map<String, Object> list : aimCodeList) {
            if (list.get("id").toString().equals(codeId)) {
                exist = true;
                break;
            }
        }
        return exist;
    }

    /**
     * 保存码值相关信息
     *
     * @param paramMap 保存数据
     * @return
     */
    @Transactional
    public Result saveIter(Map<String, Object> paramMap){
        paramMap.put("deleteFlag","0");
        String tableName = mateCodeValueMapper.getTableName(paramMap);
        paramMap.put("tableName",tableName);
        Map<String,Object> codeIdAndLvl= mateCodeValueMapper.selectCodeIdBYConstiaints(paramMap);
        if(!StringUtil.isEmpty(codeIdAndLvl)){                                       //存在新增记录
            if(!StringUtil.isEmpty(paramMap.get("nodePath")) && paramMap.get("nodePath").toString().indexOf(codeIdAndLvl.get("codeId").toString()) != -1){
                return Result.error("-1", "新增失败：新增节点已存在，上层结点是该新增节点或其子节点");
            }else{
                paramMap.put("codeId", codeIdAndLvl.get("codeId"));
                paramMap.put("oldLvl", codeIdAndLvl.get("oldLvl"));
                this.updateIter(paramMap);
            }
        } else {                                                                   //不存在新增记录
            String seq = mateCodeValueMapper.selectMaxCodeId(paramMap);
            seq = StringUtil.isEmpty(seq) ? "1" : String.valueOf(Integer.parseInt(seq)+1);
            paramMap.put("seq",seq);
            if(!StringUtil.isEmpty(paramMap.get("levelId"))){                     //递归码表
                paramMap.put("upperId","0".equals(paramMap.get("parentId").toString()) ? "" : paramMap.get("parentId").toString());
                paramMap.put("nodePath",!StringUtil.isEmpty(paramMap.get("nodePath")) ? paramMap.get("nodePath").toString().trim()+"."+seq : seq);
                if (!StringUtil.isEmpty(paramMap.get("corpId"))) {
                    mateCodeValueMapper.saveIterCorpId(paramMap);
                } else {
                    mateCodeValueMapper.saveIter(paramMap);
                }
            }else{                                                                //普通码表
                paramMap.put("upperId","");
                paramMap.put("levelId","1");
                paramMap.put("nodePath", seq);
                if (!StringUtil.isEmpty(paramMap.get("corpId"))) {
                    mateCodeValueMapper.saveIterCorpId(paramMap);
                } else {
                    mateCodeValueMapper.saveIter(paramMap);
                }
            }
        }
        return Result.OK_EMPTY;
    }

    /**修改码值相关信息
     *
     * @param paramMap 保存数据
     * @return
     */
    @Transactional
    public Result updateIter(Map<String, Object> paramMap){
        String tableName = mateCodeValueMapper.getTableName(paramMap);
        paramMap.put("tableName",tableName);
        paramMap.put("deleteFlag","0");
        if (!StringUtil.isEmpty(paramMap.get("checkFlag")) && "1".equals(paramMap.get("checkFlag").toString())) {
            List<Map<String, Object>> list = mateCodeValueMapper.queryUniqueFlag(paramMap);
            if (list != null && list.size() > 0) {
                return Result.error(Constant.EXIST,"该业务类型的业务码值重复");
            }
        }
        if(!StringUtil.isEmpty(paramMap.get("levelId"))){                        //递归码表
            paramMap.put("parentId", "0".equals(paramMap.get("parentId"))? "" : paramMap.get("parentId").toString());
            if(!StringUtil.isEmpty(paramMap.get("nodePath")) && paramMap.get("nodePath").equals(paramMap.get("oldNodePath"))){
                if (!StringUtil.isEmpty(paramMap.get("corpId"))) {
                    mateCodeValueMapper.updateIterCorpId(paramMap);
                } else {
                    mateCodeValueMapper.updateIter(paramMap);
                }
            }else {
                paramMap.put("nodePath",!StringUtil.isEmpty(paramMap.get("nodePath")) ? paramMap.get("nodePath").toString().trim()+"."+paramMap.get("codeId").toString() : paramMap.get("codeId").toString());
                paramMap.put("codeIds", StringUtil.isEmpty(paramMap.get("oldParentId")) ? paramMap.get("codeId").toString()+"." : "."+paramMap.get("codeId").toString()+".");
                if (!StringUtil.isEmpty(paramMap.get("corpId"))) {
                    mateCodeValueMapper.updateIterCorpId(paramMap);
                } else {
                    mateCodeValueMapper.updateIter(paramMap);
                }
                List<Map<String, Object>> mapList = mateCodeValueMapper.selectChildren(paramMap);
                String splitCodeId = paramMap.get("codeId").toString();
                String splitPath = (String) paramMap.get("nodePath");
                Integer minLvl = Integer.parseInt(paramMap.get("oldLvl").toString()) - Integer.parseInt(paramMap.get("levelId").toString());
                for(Map map : mapList){
                    paramMap.put("businessCode", map.get("businessCode"));
                    paramMap.put("cnName", map.get("title"));
                    paramMap.put("parentId", map.get("parentId"));
                    paramMap.put("levelId", Integer.parseInt(map.get("lvl").toString()) - minLvl);
                    paramMap.put("leafFlag", map.get("leafFlag"));
                    paramMap.put("deleteFlag", "0");
                    paramMap.put("isValid", map.get("isValid"));
                    paramMap.put("orderFlag", map.get("orderFlag"));
                    paramMap.put("remarks", map.get("remarks"));
                    paramMap.put("nodePath", splitPath + map.get("path").toString().substring(map.get("path").toString().indexOf(splitCodeId) + splitCodeId.length()));
                    paramMap.put("codeId", map.get("id"));
                    if (!StringUtil.isEmpty(paramMap.get("corpId"))) {
                        mateCodeValueMapper.updateIterCorpId(paramMap);
                    } else {
                        mateCodeValueMapper.updateIter(paramMap);
                    }
                }
            }
        }else{                                                                  //展平码表
            paramMap.put("levelId","1");
            paramMap.put("parentId","");
            paramMap.put("nodePath", paramMap.get("codeId").toString());
            if (!StringUtil.isEmpty(paramMap.get("corpId"))) {
                mateCodeValueMapper.updateIterCorpId(paramMap);
            } else {
                mateCodeValueMapper.updateIter(paramMap);
            }
        }
        return Result.OK_EMPTY;
    }

    /**
     * 删除迭代码值信息
     *
     * @param paramMap 请求参数
     * @return  操作返回结果
     */
    @Transactional
    public Result deleteIterBatch(Map<String, Object> paramMap) {
        String tableName = mateCodeValueMapper.getTableName(paramMap);
        paramMap.put("tableName",tableName);
        mateCodeValueMapper.deleteIterBatch(paramMap);
        return Result.OK_EMPTY;
    }

    /**
     *启用/停用迭代值信息
     *
     * @param paramMap 请求参数
     * @return  操作返回结果
     */
    @Transactional
    public Result stopOrStartIterBatch(Map<String, Object> paramMap) {
        String tableName = mateCodeValueMapper.getTableName(paramMap);
        paramMap.put("tableName",tableName);
        paramMap.put("isValid", "stop".equals(paramMap.get("flag").toString()) ? "0" : "1");
        mateCodeValueMapper.stopOrStartIterBatch(paramMap);
        return Result.OK_EMPTY;
    }

    /**
     * 导出码值信息
     *
     * @param paramMap 请求参数
     * @return
     */
    public  List<Map<String,Object>> selectSheet1(Map<String, Object> paramMap){
        Map<String,Object>  map = new HashMap<>();
        map.put("list",(List)paramMap.get("dataList"));
        return  mateCodeValueMapper.selectSheet1(map);
    }

    /**
     * 导出迭代/展平码表信息
     *
     * @param mapList
     * @return
     */
    public  List<Map<String,Object>> selectSheetRecOrCommon(List<Map<String, Object>> mapList){
        List<Map<String, Object>> dataList = new ArrayList<>();
        List<Map<String, Object>> dataBatchList;
        int batchCount = 100;
        int batchLastIndex = batchCount;//每批最后一个的下标
        for (int index = 0; index < mapList.size(); ) {
            if (batchLastIndex >= mapList.size()) {
                batchLastIndex = mapList.size();
                dataBatchList = mateCodeValueMapper.selectSheetRecOrCommon(mapList.size() == 1 ? mapList : mapList.subList(index, batchLastIndex));
                dataList.addAll(dataBatchList);
                break;
            } else {
                dataBatchList = mateCodeValueMapper.selectSheetRecOrCommon(mapList.subList(index, batchLastIndex));
                dataList.addAll(dataBatchList);
                index = batchLastIndex;
                batchLastIndex = index + batchCount;
            }
        }
        return dataList;
    }

    /**
     * 导入码值数据前校验数据有效性
     *
     * @param workbook       工作簿
     * @param totalColumn    总列数
     * @param colInfosList   数据检查规则（1-列中文名；2-NULL标志；3-主键标志；4-校验数据区域）
     * @return Object （检验未通过：返回STRING-错误信息；检验通过：返回Map）
     * @throws IOException
     */
    public Object checkCodeExcelData(XSSFWorkbook workbook, int totalColumn ,ArrayList<String[]> colInfosList) throws IOException {
        List<String[]> arrList = new ArrayList<>();                                  //EXCEL所有的导入数据
        Map<String,Object> tableMap = new HashMap<>();                               //工作薄的表名
        List<String> constraintsList = new ArrayList<>();                            //导入约束验证
        List<String> tableList = new ArrayList<>();                                  //表名限制
        Map<String, Object> validMap = new HashMap<>();                              //验证Map集合
        Map<String, Object> bussCodeTypeMap = new HashMap<>();                       //证码值类型集合
        boolean hasErr = false;                                                      //存在错误标志位
        StringBuilder errInfo = new StringBuilder();                                 //全局错误信息
        StringBuilder rowErrInfo;                                                    //行错误信息
        DataFormatter formatter = new DataFormatter();
        List<Map<String,Object>> TableNamelist = mateCodeValueMapper.getCodeTableList();
        for (Map map : TableNamelist){
            tableList.add(map.get("DATAUSER").toString()+ "." + map.get("CNNAME").toString());
        }
        validMap.put("tableList_upper", tableList);
        ZipSecureFile.setMinInflateRatio(-1.0d);
        errInfo.append("<br/>");
        errInfo.append("**********   <span style='color:red;font-weight:bold;'>导入结果：失败</span>   **********");
        if (workbook.getNumberOfSheets() < 2) {
            //如果导入文件工作簿数不足，则记录错误信息，返回
            errInfo.append("<br/><br/><br/>工作簿不足，导入文件应具备" + 2 + "个工作簿，请使用模板导入");
            return errInfo.toString();
        }
        //第一个工作簿
        errInfo.append("<br/><br/><br/>*** 开始检查"+ workbook.getSheetName(0) +" ***");
        XSSFSheet sheet = workbook.getSheetAt(0);
        sheet.disableLocking();
        String[] colNames = colInfosList.get(0);                                      //数据检查规则-列中文名
        String[] colNulls = colInfosList.get(1);                                      //数据检查规则-NULL标志
        String[] colConstraints = colInfosList.get(2);                                //数据检查规则-主键标志
        String[] colValueLimits = colInfosList.get(3);                                //数据检查规则-数据特殊校验区域
        int reallTotal = 0;
        Map<String, Object> judgeMap;
        int count = sheet.getRow(0).getPhysicalNumberOfCells();
        if (count != totalColumn) {
            //列数错误，则记录错误信息
            errInfo.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;列数错误，当前有" + count + "列，实际需要" + totalColumn + "列");
            return errInfo.toString();
        }
        for (int i = 1; i <= sheet.getLastRowNum(); i++) {
            //遍历每一行（从工作簿第1行开始读取）
            XSSFRow row = sheet.getRow(i);
            if (row != null &&  !ExcelUtil.concatString(row, totalColumn, formatter)) {
                reallTotal += 1;
                boolean rowErr = false;                                               //行数据错误标志位
                rowErrInfo = new StringBuilder();
                String[] importData = new String[totalColumn];                        //认定规则基本信息数据
                rowErrInfo.append("<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第 " + (i + 1) + " 行：");
                //其他校验
                validMap.put("row", row);
                validMap.put("colNames", colNames);
                validMap.put("hasErr", hasErr);
                validMap.put("rowErr", rowErr);
                validMap.put("rowErrInfo", rowErrInfo);
                validMap.put("constraintsList", constraintsList);
                judgeMap = validCell(validMap,colConstraints, colValueLimits, colNulls,importData, totalColumn, formatter);
                rowErrInfo = (StringBuilder) judgeMap.get("rowErrInfo");
                importData = (String[]) judgeMap.get("importData");
                hasErr = (boolean) judgeMap.get("hasErr");
                rowErr = (boolean) judgeMap.get("rowErr");
                constraintsList.add(ExcelUtil.getStringCellValues(formatter, row.getCell(1)).toUpperCase(Locale.ENGLISH));
                bussCodeTypeMap.put(ExcelUtil.getStringCellValues(formatter, row.getCell(1)).toUpperCase(Locale.ENGLISH), ExcelUtil.getStringCellValues(formatter, row.getCell(4)));
                if (rowErr) {
                    //将行错误信息记录到全局错误信息中
                    errInfo.append(rowErrInfo.toString());
                }else {
                    arrList.add(importData);
                    tableMap.put(ExcelUtil.getStringCellValues(formatter, row.getCell(1)).toUpperCase(Locale.ENGLISH),ExcelUtil.getStringCellValues(formatter, row.getCell(0)));
                }
            } else {
                break;
            }
        }
        //返回最终结果
        if (hasErr) {
            return errInfo.toString();
        } else {
            StringBuilder rightInfo = new StringBuilder();
            rightInfo.append("<br/>");
            rightInfo.append("**********   <span style='color:green;font-weight:bold;'>导入结果：成功</span>   **********");
            rightInfo.append("<br/><br/>"+ sheet.getSheetName() +" 共计导入 <span style='color:blue;font-weight:bold;'>" + reallTotal + "</span> 条" + workbook.getSheetAt(0).getSheetName() + "数据");
            Map<String,Object> mapList = new HashMap<>();
            mapList.put("dataList", arrList);
            mapList.put("appAndBussList", constraintsList);
            mapList.put("tableName", tableMap);
            mapList.put("bussCodeType", bussCodeTypeMap);
            mapList.put("rightInfo", rightInfo.toString());
            return mapList;
        }
    }

    /**
     * 导入码值详细数据前校验数据有效性
     *
     * @param workbook        工作簿
     * @param totalColumn     总列数
     * @param colInfosList    数据检查规则（1-列中文名；2-NULL标志；3-主键标志；4-校验数据区域）
     * @param appAndBussList  应用名称码值类型集合
     * @param bussCodeTypeMap 码值类型集合
     * @return Object （检验未通过：返回STRING-错误信息；检验通过：返回Map）
     * @throws IOException
     */
    public Object checkResAndComExcelData(XSSFWorkbook workbook, int totalColumn ,ArrayList<String[]> colInfosList, List<String> appAndBussList, Map<String, Object> bussCodeTypeMap) throws IOException {
        Map<String,  List<String[]>> codeTypeMap = new HashMap<>();                   //EXCEL所有的导入数据
        Map<String, Object> validMap = new HashMap<>();                               //验证Map集合
        boolean hasErr = false;                                                       //存在错误标志位
        StringBuilder rowErrInfo;                                                     //行错误信息
        StringBuilder errInfo = new StringBuilder();                                  //全局错误信息
        DataFormatter formatter = new DataFormatter();
        ZipSecureFile.setMinInflateRatio(-1.0d);
        errInfo.append("<br/>");
        errInfo.append("**********   <span style='color:red;font-weight:bold;'>导入结果：失败</span>   **********");
        //第二个工作簿
        errInfo.append("<br/><br/><br/>*** 开始检查"+ workbook.getSheetName(1) + "***");
        XSSFSheet sheet = workbook.getSheetAt(1);
        List<String> constraintsList = new ArrayList<>();                            //导入约束验证(唯一约束)
        String[] colNames = colInfosList.get(0);                                      //数据检查规则-列中文名
        String[] colConstraints = colInfosList.get(2);                                //数据检查规则-主键标志
        String[] colNulls = colInfosList.get(1);                                      //数据检查规则-NULL标志
        String[] colValueLimits = colInfosList.get(3);                                //数据检查规则-数据特殊校验区域
        int cellCount = sheet.getRow(0).getPhysicalNumberOfCells();         //导入列数
        int reallTotal = 0;
        //校验集合
        String appAndBussStr;
        Map<String, Object> judgeMap;
        List<String[]> dataList;
        List<String> parentList;
        Map<String,  List<String>> upperMap = new HashMap<>();
        for (String appAndBuss : appAndBussList){
            codeTypeMap.put(appAndBuss, new ArrayList<>());
            upperMap.put(appAndBuss, new ArrayList<>());
        }
        if (cellCount != totalColumn) {
            errInfo.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;列数错误，当前有" + cellCount + "列，实际需要" + totalColumn + "列");
            return errInfo.toString();
        }
        for (int j = 1; j <= sheet.getLastRowNum(); j++) {
            //遍历每一行（从工作簿第1行开始读取）
            XSSFRow row = sheet.getRow(j);
            if (row != null && !ExcelUtil.concatString(row, totalColumn, formatter)) {
                reallTotal += 1;
                rowErrInfo = new StringBuilder();
                boolean rowErr = false;                                            //行数据错误标志位
                String[] ruleDta = new String[totalColumn];                        //认定规则基本信息数据
                rowErrInfo.append("<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第 " + (j + 1) + " 行：");
                //其他校验
                appAndBussStr = ExcelUtil.getStringCellValues(formatter, row.getCell(0));
                 if(!appAndBussList.contains(appAndBussStr)){
                    rowErrInfo.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp<"+ colNames[0] +">在第一个sheet页中不存在");
                    hasErr = true;
                    rowErr = true;
                } else {
                     parentList = upperMap.get(appAndBussStr);
                     parentList.add(ExcelUtil.getStringCellValues(formatter, row.getCell(2)));
                     validMap.put("parentList", parentList);
                     validMap.put("constraintsList", constraintsList);
                     validMap.put("2", "数字".equals(bussCodeTypeMap.get(appAndBussStr).toString()) ? "true" : "false");
                     validMap.put("row", row);
                     validMap.put("colNames", colNames);
                     validMap.put("rowErr", rowErr);
                     validMap.put("hasErr", hasErr);
                     validMap.put("rowErrInfo", rowErrInfo);
                     judgeMap = validCell(validMap,colConstraints, colValueLimits, colNulls,ruleDta, totalColumn, formatter);
                     hasErr = (boolean) judgeMap.get("hasErr");
                     rowErr = (boolean) judgeMap.get("rowErr");
                     rowErrInfo = (StringBuilder) judgeMap.get("rowErrInfo");
                     ruleDta = (String[]) judgeMap.get("importData");
                     constraintsList.add(ExcelUtil.getStringCellValues(formatter, row.getCell(0)) + "-" + ExcelUtil.getStringCellValues(formatter, row.getCell(2)));
                 }
                if (rowErr) {
                    //将行错误信息记录到全局错误信息中
                    errInfo.append(rowErrInfo.toString());
                }else {
                    dataList = codeTypeMap.get(appAndBussStr);
                    dataList.add(ruleDta);
                    codeTypeMap.put(appAndBussStr, dataList);
                }
            } else {
                break;
            }
        }
        //返回最终结果
        if (hasErr) {
            return errInfo.toString();
        } else {
            StringBuilder rightInfo = new StringBuilder();
            rightInfo.append("<br/>");
            rightInfo.append("<br/><br/>"+ sheet.getSheetName() +" 共计导入 <span style='color:blue;font-weight:bold;'>" + reallTotal + "</span> 条" + workbook.getSheetAt(1).getSheetName() + "数据");
            Map<String,Object> mapList = new HashMap<>();
            mapList.put("dataMap", codeTypeMap);
            mapList.put("upperMap", upperMap);
            mapList.put("rightInfo", rightInfo.toString());
            return mapList;
        }
    }

    /**
     * 导入EXCEL数据
     *
     * @param mapList      导入的系统第一个EXCEL数据
     * @param resOrComList 导入的系统第二个EXCEL数据
     * @param optUserId    当前登录用户代码
     */
    @Transactional
    public void doImportCodeExcelData(Map<String,Object> mapList,Map<String,Object> resOrComList, String optUserId) {
        Map<String,Object> dataMap;                                                                   //批量导入数据
        Map<String,Object> insertMap;                                                                 //封装每行对象
        List<Map<String,Object>> insertList = new ArrayList<>();                                      //新增
        List<Map<String,Object>> updateList = new ArrayList<>();                                      //修改
        List<String[]> dataMainList = (List) mapList.get("dataList");                                 //导入第一个sheet数据
        List<String> appAndBussList = (ArrayList) mapList.get("appAndBussList");                      //导入码值类型与应用标识集合
        Map<String,  List<String[]>> dataResOrComMap = (Map) resOrComList.get("dataMap");             //第二个sheet页数据
        Map<String, Object> tableMap = (Map) mapList.get("tableName");                                //导入表名集合
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");               //初始化时间
        List<Map<String,Object>> tableNameList = mateCodeValueMapper.getCodeTableList();         //码表对象List
        List<Map<String, Object>>  appAllBussLst = mateCodeValueMapper.selectAllAppAndBuss();         //码表对象List
//        List<Map<String, Object>>  allSystemCode = mateCodeValueMapper.selectAllSystemCode();         //查询所有系统码值
        List<Map<String, Object>> groupTypeList;
        String seq = mateCodeValueMapper.maxCodeTypeId();
        seq = StringUtil.isEmpty(seq)? "0" : seq;
        int middleValue;
        Map<String, Object> middleMap;
        //遍历第一个sheet页数据
        dataMap = new HashMap<>();
        String codeTableId;
        for(int i=0; i< dataMainList.size(); i++){
            insertMap = new HashMap<>();
            insertMap.put("businessType", dataMainList.get(i)[1].toUpperCase(Locale.ENGLISH));
            insertMap.put("cnName", dataMainList.get(i)[2]);
            insertMap.put("codeStoreType", "递归码表".equals(dataMainList.get(i)[3]) ? "RECURSION" : "COMMON");
            insertMap.put("dataStoreType", "数字".equals(dataMainList.get(i)[4]) ? "NUMBER" : "STRING");
            insertMap.put("activeFlag", "启用".equals(dataMainList.get(i)[5]) ? "1" : "0");
            insertMap.put("orderFlag", dataMainList.get(i)[6]);
            insertMap.put("stsRecodeType","FREE");
            insertMap.put("remarks", dataMainList.get(i)[9]);
            insertMap.put("deleteFlag", "0");
            insertMap.put("debugFlag", "0");
            insertMap.put("corpId", dataMainList.get(i)[7]);
            middleValue = containsByKey( appAllBussLst, appAndBussList.get(i).toUpperCase(Locale.ENGLISH), "id");
            if(-1 == middleValue){
                middleMap = new HashMap<>();
                codeTableId = selectByValue(tableNameList, dataMainList.get(i)[0].substring(dataMainList.get(i)[0].indexOf(".")+1).toUpperCase(Locale.ENGLISH));
                seq = String.valueOf(Integer.parseInt(seq) + 1);
                insertMap.put("codeTypeId", seq);
                insertMap.put("creatUser", optUserId);
                insertMap.put("creatTime", format.format(new Date()));
                insertMap.put("updateUser", optUserId);
                insertMap.put("updateTime", format.format(new Date()));
                insertMap.put("tableName", codeTableId);
                middleMap.put("id", dataMainList.get(i)[1].toUpperCase(Locale.ENGLISH));
                middleMap.put("codeTypeId", seq);
                middleMap.put("codeTableId", codeTableId);
                appAllBussLst.add(middleMap);
                insertList.add(insertMap);
            }else{
                insertMap.put("tableName", appAllBussLst.get(middleValue).get("codeTableId"));
                tableMap.put(dataMainList.get(i)[1].toUpperCase(Locale.ENGLISH), appAllBussLst.get(middleValue).get("tableName"));
                insertMap.put("updateUser", optUserId);
                insertMap.put("updateTime", format.format(new Date()));
                //SYSTEM_FLAG = 1 系统配置不能修改 SYSTEM_FLAG = 0 可修改
                if ("0".equals(appAllBussLst.get(middleValue).get("systemFlag").toString())) {
                    //导入默认码表对象不能修改
                    updateList.add(insertMap);
                }
            }
        }
        String corpFlag = "0";
        if(updateList.size()>0){
            batchInsertOrUpdate(dataMap, updateList, "update", corpFlag);
        }
        if(insertList.size()>0){
            dataMap.clear();
            batchInsertOrUpdate(dataMap, insertList, "insert", corpFlag);
        }
        dataMap.clear();
        //遍历剩余sheet页数据
        //String[] str;
        String updateCodeId;
        String addCodeId;
        Map<String, Object> updateMiddleMap;
        for(String key : dataResOrComMap.keySet()){
            List<String[]> dataResOrComList =  dataResOrComMap.get(key);  //每个sheet对应的数据
            String tableName = (String)tableMap.get(key);
            insertMap = new HashMap<>();
            insertMap.put("tableName", tableName);
            //str = key.split("-");
            insertMap.put("bussinessType", key.toUpperCase(Locale.ENGLISH));
            groupTypeList = mateCodeValueMapper.selectAllCodeId(insertMap);
            addCodeId = mateCodeValueMapper.selectMaxCodeId(insertMap);
            addCodeId = StringUtil.isEmpty(addCodeId)? "0" : addCodeId;
            updateList.clear();
            insertList.clear();
            for(int i=0; i< dataResOrComList.size(); i++){
                insertMap = new HashMap<>();
                for(int k=0; k< dataMainList.size(); k++){
                    if (dataResOrComList.get(i)[0].toUpperCase(Locale.ENGLISH).equals(dataMainList.get(k)[1].toUpperCase(Locale.ENGLISH))) {
                        if (!StringUtil.isEmpty(dataMainList.get(k)[7])) {
                            insertMap.put("corpId", dataMainList.get(k)[7]);
                        }
                    }
                }
                insertMap.put("title", dataResOrComList.get(i)[1]);
                insertMap.put("businessCode", dataResOrComList.get(i)[2]);
                insertMap.put("leafFlag", "目录".equals(dataResOrComList.get(i)[4].trim())? "0" : "1");
                insertMap.put("activeFlag", "启用".equals(dataResOrComList.get(i)[5]) ? "1" : "0");
                insertMap.put("remarks",dataResOrComList.get(i)[7]);
                insertMap.put("orderFlag", dataResOrComList.get(i)[6]);
                insertMap.put("deleteFlag", "0");
                middleValue = containsByKey(groupTypeList, dataResOrComList.get(i)[0].toUpperCase(Locale.ENGLISH) + "-" + dataResOrComList.get(i)[2], "id");
                if(-1 != middleValue){                          //修改
                    updateMiddleMap = new HashMap<>();
                    middleMap = groupTypeList.get(middleValue);
                    updateCodeId = middleMap.get("codeId").toString();
                    insertMap.put("codeTypeId",middleMap.get("codeTypeId"));
                    insertMap.put("id",middleMap.get("codeId"));
                    updateMiddleMap.put("id", middleMap.get("id"));
                    updateMiddleMap.put("codeTypeId", middleMap.get("codeTypeId"));
                    updateMiddleMap.put("codeId", middleMap.get("codeId"));
                    groupTypeList.remove(middleValue);
                    if(!StringUtil.isEmpty(dataResOrComList.get(i)[3])){      //父节点存在
                        middleValue = containsByKey(groupTypeList, dataResOrComList.get(i)[0].toUpperCase(Locale.ENGLISH) + "-" + dataResOrComList.get(i)[3], "id");
                        middleMap = groupTypeList.get(middleValue);
                        insertMap.put("path",middleMap.get("path") + "." + updateCodeId);
                        insertMap.put("parentId",middleMap.get("codeId"));
                        insertMap.put("lvl",Integer.parseInt(middleMap.get("lvl").toString())+1);
                    } else {
                        insertMap.put("lvl", 1);
                        insertMap.put("path", updateCodeId);
                        insertMap.put("parentId","");
                    }
                    updateMiddleMap.put("upperId", insertMap.get("codeId"));
                    updateMiddleMap.put("path", insertMap.get("path"));
                    updateMiddleMap.put("lvl", insertMap.get("lvl"));
                    groupTypeList.add(updateMiddleMap);
                    updateList.add(insertMap);
                }else{                                                     //新增码值
                    updateMiddleMap = new HashMap<>();
                    addCodeId =  String.valueOf(Integer.parseInt(addCodeId) + 1);
                    insertMap.put("id",addCodeId);
                    insertMap.put("codeTypeId", containsAddCodeId(appAllBussLst, dataResOrComList.get(i)[0].toUpperCase(Locale.ENGLISH)));
                    if(!StringUtil.isEmpty(dataResOrComList.get(i)[3])){
                        middleValue = containsByKey(groupTypeList, dataResOrComList.get(i)[0].toUpperCase(Locale.ENGLISH) + "-" + dataResOrComList.get(i)[3], "id");
                        middleMap = groupTypeList.get(middleValue);
                        insertMap.put("parentId",middleMap.get("codeId"));
                        insertMap.put("path",middleMap.get("path") + "." + addCodeId);
                        insertMap.put("lvl",Integer.parseInt(middleMap.get("lvl").toString())+1);
                    } else {
                        insertMap.put("lvl", 1);
                        insertMap.put("path", addCodeId);
                        insertMap.put("parentId","");
                    }
                    updateMiddleMap.put("id", dataResOrComList.get(i)[0].toUpperCase(Locale.ENGLISH) + "-" + dataResOrComList.get(i)[2]);
                    updateMiddleMap.put("codeTypeId", containsAddCodeId(appAllBussLst, dataResOrComList.get(i)[0].toUpperCase(Locale.ENGLISH)));
                    updateMiddleMap.put("codeId", addCodeId);
                    updateMiddleMap.put("path", insertMap.get("path"));
                    updateMiddleMap.put("upperId", insertMap.get("codeId"));
                    updateMiddleMap.put("lvl", insertMap.get("lvl"));
                    groupTypeList.add(updateMiddleMap);
                    insertList.add(insertMap);
                }
            }
            dataMap.put("tableName",tableName);
            Map<String, Object> paramMap0 = new HashMap<>();
            String[] str0 = tableName.split("\\.");
            String corpFlag0 = "0";
            if (str0.length > 1) {
                paramMap0.put("databaseUser", str0[0]);
                paramMap0.put("tabName", str0[1]);
                corpFlag0 = mateCodeValueMapper.selTabType(paramMap0);
            }
            if(updateList.size()>0){
                batchInsertOrUpdate(dataMap, updateList, "update", corpFlag0);
            }
            if(insertList.size()>0){
                dataMap.remove("resOrComUpdateData");
                batchInsertOrUpdate(dataMap, insertList, "insert", corpFlag0);
            }
        }
    }

    /**
     * 查询应用标识id
     *
     * @param str         应用名称
     * @param aimList     目标List
     * @return String     返回对应CODE
     */
    private String selectByValue(List<Map<String,Object>> aimList, String  str){
        String strCode = null;
        for(Map map : aimList){
            if(str.equals(map.get("CNNAME").toString())){
                strCode = map.get("CODE").toString();
                break;
            }
        }
        return strCode;
    }

    /**
     * 查询所有是否存目标字符
     * @param aminList 目标List
     * @param str 码值标识
     * @param key 键值
     * @return
     */
    private int containsByKey(List<Map<String, Object>> aminList, String str, String key){
        for(int i = 0; i < aminList.size(); i++){
            if(aminList.get(i).get(key).equals(str)){
                return i;
            }
        }
        return -1;
    }

    /**
     * 查询业务标识
     *
     * @param aminList        目标集合
     * @param bussCodeType    码值类型
     * @return
     */
    private String containsAddCodeId(List<Map<String, Object>> aminList, String bussCodeType){
        String str;
        for(Map map : aminList){
            str = map.get("id").toString();
            if(str.equals(bussCodeType)){
                return map.get("codeTypeId").toString();
            }
        }
        return null;
    }


    /**
     * 查询码值类型也业务码值是否唯一
     * @param tableName      表名
     * @param codeTypeId     码值类型
     * @return  List<String> 约束结果集
     */
    private HashSet<String> selectConList(String tableName, String codeTypeId){
        Map<String, Object> constraintsMap =  new HashMap<>();
        HashSet<String> constraintsList = new HashSet<>();
        constraintsMap.put("tableName", tableName);
        constraintsMap.put("codeTypeId", codeTypeId);
        for(Map map: mateCodeValueMapper.getIterDataList(constraintsMap)){
            constraintsList.add(map.get("businessCode").toString());
        }
        return constraintsList;
    }

    /**
     * 检验每个单元格
     *
     * @param validMap       校验集合
     * @param colConstraints 约束集
     * @param colValueLimits 特殊数据校验
     * @param colNulls       空集
     * @param importData     数据集
     * @param totalColumn    总列数
     * @param formatter      格式化字符串
     * @return
     */
    private Map<String, Object> validCell(Map<String, Object> validMap, String[] colConstraints, String[] colValueLimits, String[] colNulls,String[] importData, int totalColumn, DataFormatter formatter){
        XSSFRow row = (XSSFRow) validMap.get("row");
        String[] colNames = (String[]) validMap.get("colNames");
        StringBuilder rowErrInfo = (StringBuilder) validMap.get("rowErrInfo");
        boolean hasErr;
        boolean rowErr;
        String validData = "";
        for (int j = 0; j < totalColumn; j++){
            XSSFCell cell = row.getCell(j);
            if (cell == null || StringUtil.isEmpty(ExcelUtil.getStringCellValues(formatter, cell))) {
                if ("NOTNULL".equals(colNulls[j])) {
                    rowErrInfo.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<" + colNames[j] + ">不能为空");
                    hasErr = true;
                    rowErr = true;
                    validMap.put("rowErrInfo", rowErrInfo);
                    validMap.put("hasErr", hasErr);
                    validMap.put("rowErr", rowErr);
                } else {
                    importData[j] = "";
                }
            }else{
//                cell.setCellType(CellType.STRING);
                importData[j] = ExcelUtil.getStringCellValues(formatter, cell).trim();
                if(colConstraints[j].indexOf("CONSTRAINTS") != -1){
                    validData = validData + ExcelUtil.getStringCellValues(formatter, cell).trim() +"-";
                    validMap = this.validPrimeAndCon(colConstraints[j],validMap, validData.substring(0,validData.length()-1), j);
                }
                if(!StringUtil.isEmpty(colValueLimits[j])){
                    validMap = this.validOtherData(colValueLimits, validMap, ExcelUtil.getStringCellValues(formatter, cell).trim(), j);
                }
            }
        }
        validMap.put("importData", importData);
        return validMap;
    }


    /**
     * 主键与约束校验
     *
     * @param colConstraints 约束集
     * @param validMap       验证集
     * @param validConData   待验证约束数据
     * @param index          待验证下标
     * @return
     */
    private Map<String, Object> validPrimeAndCon(String colConstraints, Map<String, Object> validMap,String  validConData,int index){
        String[] colNames = (String[]) validMap.get("colNames");
        StringBuilder rowErrInfo = (StringBuilder) validMap.get("rowErrInfo");
        List constraintsList = (List)validMap.get("constraintsList");
        boolean hasErr = (boolean) validMap.get("hasErr");
        boolean rowErr = (boolean) validMap.get("rowErr");
        if(colConstraints.indexOf("CONSTRAINTS") != -1 && constraintsList.contains(validConData.toUpperCase(Locale.ENGLISH))){
            String[] indexCon =colConstraints.split("_");
            rowErrInfo.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
            for (int i = 1; i < indexCon.length-1; i++) {
                rowErrInfo.append("<"+ colNames[Integer.parseInt(indexCon[i])] +">与");
            }
            rowErrInfo.append("<"+ colNames[index] + ">重复");
            hasErr = true;
            rowErr = true;
        }
        validMap.put("rowErrInfo", rowErrInfo);
        validMap.put("hasErr", hasErr);
        validMap.put("rowErr", rowErr);
        return validMap;
    }

    /**
     * 其他限制校验
     *
     * @param colValueLimits   验证数据区域集
     * @param validMap         验证集
     * @param validData        待验证数据
     * @param index            下标
     * @return
     */
    private Map<String, Object> validOtherData(String[] colValueLimits, Map<String, Object> validMap, String validData, int index){
        StringBuilder rowErrInfo = (StringBuilder) validMap.get("rowErrInfo");
        boolean hasErr = (boolean) validMap.get("hasErr");
        String[] colNames = (String[]) validMap.get("colNames");
        boolean rowErr = (boolean) validMap.get("rowErr");
        HashSet strSet = new HashSet();
        if(!StringUtil.isEmpty(colValueLimits[index]) && colValueLimits[index].indexOf("-") != -1){     //等值校验
            String[] str = colValueLimits[index].split("-");
            String error;
            for(int i = 0; i< str.length; i++){
                strSet.add(str[i]);
            }
            if(!strSet.contains(validData)){
                error = strSet.size() > 1 ? colValueLimits[index].replaceAll("-","、") : str[1];
                rowErrInfo.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<"+ colNames[index] + ">填入错误，请输入"+ error);
                hasErr = true;
                rowErr = true;
            }
        }
        if((!StringUtil.isEmpty(colValueLimits[index]) && colValueLimits[index].indexOf("number") != -1) || (!StringUtil.isEmpty(validMap.get(String.valueOf(index))) && "true".equals(validMap.get(String.valueOf(index))))){  //正则校验
            Pattern pattern = Pattern.compile("^\\d+$");
            if (!pattern.matcher(validData).matches()) {
                rowErrInfo.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<"+ colNames[index] + ">请输入正整数");
                hasErr = true;
                rowErr = true;
            }
        }
        if(!StringUtil.isEmpty(colValueLimits[index]) && colValueLimits[index].indexOf("List") != -1){  //其他包含校验
            validData = colValueLimits[index].indexOf("upper") == -1 ? validData : validData.toUpperCase(Locale.ENGLISH);
            List arrayList = (List) validMap.get(colValueLimits[index]);
            if (!arrayList.contains(validData)) {
                rowErrInfo.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<"+ colNames[index] + ">不存在此"+colNames[index]);
                hasErr = true;
                rowErr = true;
            }
        }
        if(!StringUtil.isEmpty(colValueLimits[index]) && colValueLimits[index].indexOf("string") != -1){  //其他包含校验
            Pattern pattern = Pattern.compile("^[a-zA-Z]+[a-zA-Z0-9_]*(?<![_])$");
            if (!pattern.matcher(validData).matches()) {
                rowErrInfo.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<"+ colNames[2] + ">类型错误：首位必须是字母，可包含下划线和数字且不能以下划线结尾");
                hasErr = true;
                rowErr = true;
            }
        }
        validMap.put("rowErrInfo", rowErrInfo);
        validMap.put("hasErr", hasErr);
        validMap.put("rowErr", rowErr);
        return validMap;
    }

    /**
     * 批量插入和修改码表数据
     *
     * @param dataMap    目标map集合
     * @param aimList 目标List集合
     * @param updateFalg 修改标识
     */
    private void batchInsertOrUpdate(Map<String, Object> dataMap, List<Map<String, Object>> aimList, String updateFalg, String corpFlag) {
        int batchCount = 500;
        int batchLastIndex = batchCount;
        for (int index = 0; index < aimList.size(); ) {
            if (batchLastIndex >= aimList.size()) {
                batchLastIndex = aimList.size();
                insertOrUpdateData(dataMap, index, batchLastIndex, aimList, updateFalg, corpFlag);
                break;
            } else {
                insertOrUpdateData(dataMap, index, batchLastIndex, aimList, updateFalg, corpFlag);
                index = batchLastIndex;//设置下一批下标
                batchLastIndex = index + batchCount;
            }
        }
    }


    /**
     * 插入或修改数据
     *
     * @param dataMap        目标map集合
     * @param index          批量操作开始下标
     * @param batchLastIndex 批量操作结束下标
     * @param aimList        插入或修改list集合
     * @param updateFlag     修改标识
     */
    private void insertOrUpdateData(Map<String, Object> dataMap, int index, int batchLastIndex,  List<Map<String, Object>> aimList, String updateFlag, String corpFlag){
        if(StringUtil.isEmpty(dataMap.get("tableName"))){
            if("insert".equals(updateFlag)){
                dataMap.put("insertList", aimList.subList(index, batchLastIndex));
                mateCodeValueMapper.insertBatch(dataMap);
            }else{
                dataMap.put("updateList", aimList.subList(index, batchLastIndex));
                mateCodeValueMapper.updateBatch(dataMap);
            }
        } else {
            if("insert".equals(updateFlag)){
                dataMap.put("resOrComInsertData", aimList.subList(index, batchLastIndex));
                if ("1".equals(corpFlag)) {
                    mateCodeValueMapper.insertResOrComBatchCorpId(dataMap);
                } else {
                    mateCodeValueMapper.insertResOrComBatch(dataMap);
                }
            }else{
                dataMap.put("resOrComUpdateData", aimList.subList(index, batchLastIndex));
                if ("1".equals(corpFlag)) {
                    mateCodeValueMapper.updateResOrComBatchCorpId(dataMap);
                } else {
                    mateCodeValueMapper.updateResOrComBatch(dataMap);
                }
            }
        }
    }
}
